<template>
    <div class="navigate">
        <van-nav-bar title="导航" v-show="toolboxShow" class="header" left-text="" left-arrow @click-left="backToAddress()"></van-nav-bar>
        <div class="toolbox" v-show="toolboxShow">
            <div @click="showRoutePanel"><img src="@/assets/img/navi-icon.png"/></div>
            <div @click="cleanMap"><i class="el-icon-delete" style="font-size: 25px;"></i></div>
        </div>
        <!-- 导航信息提示 -->
        <div class="navi-tips" v-show="naviTipsShow">
            <i class="el-icon-close" @click="shutDownNavigate"></i>
            <div class="tips-wrapper">
                <p class="tips">{{tips}}</p>
                <p class="time-distance">{{timeDistance}}</p>
            </div>
            <img :src="imgUrl" alt="方向标识" v-show="imgUrl.length">
        </div>
        <div id="map-container"></div>
        <!-- 路线规划表单 -->
        <div class="routePanel" v-if="routePanelShow">
            <h3 style="display: inline">路线规划</h3>
            <i class="el-icon-close" style="float: right;font-size: 16px; cursor: pointer;" @click="() => {this.routePanelShow = false}"></i>
            <el-form :label-position="'left'" label-width="50px" size="mini">
                <el-form-item label="起点">
                    <el-input v-model="routeForm.startPoint" placeholder="请选择起点">
                        <el-button slot="append" icon="el-icon-coordinate" @click.prevent="getStartPoint"></el-button>
                    </el-input>
                </el-form-item>
                <el-form-item label="终点">
                    <el-input v-model="routeForm.endPoint" placeholder="请选择终点">
                        <el-button slot="append" icon="el-icon-coordinate" @click="getEndPoint"></el-button>
                    </el-input>
                </el-form-item>

                <el-form-item label="其他">
                    <el-collapse accordion>
                        <el-collapse-item style="min-width: 30px;" title="其他配置">
                            <el-form-item label="过水">
                                <el-radio-group v-model="routeForm.resourceRegion">
                                    <el-radio label="城市规划"></el-radio>
                                    <el-radio label="野外规划"></el-radio>
                                </el-radio-group>
                            </el-form-item>

                            <el-form-item label="过水">
                                <el-radio-group v-model="routeForm.resourceWater">
                                    <el-radio label="不过水"></el-radio>
                                    <el-radio label="过水"></el-radio>
                                </el-radio-group>
                            </el-form-item>

                            <el-form-item label="森林">
                                <el-radio-group v-model="routeForm.resourceForest">
                                    <el-radio label="不过森林"></el-radio>
                                    <el-radio label="过森林"></el-radio>
                                </el-radio-group>
                            </el-form-item>

                        </el-collapse-item>
                    </el-collapse>

                </el-form-item>

                <el-form-item class="item-btn">
                    <el-button type="primary" @click.stop="routeAnalyze">路径规划</el-button>
                    <el-button type="success" @click.stop="imitateNavigate" :disabled="naviDisable">模拟导航</el-button>
                    <el-button type="success" @click.stop="imitateNavigate(true)" :disabled="naviDisable">实时导航</el-button>
                </el-form-item>
            </el-form>

        </div>
    </div>
</template>

<script>
    import mapboxgl from "mapbox-gl"
    import "mapbox-gl/dist/mapbox-gl.css"
    import axios from "axios"
    import * as turf from '../../public/static/forLeaflet/turf/turf'

    export default {
        name: "NavigationMap",
        data() {
            return {
                tips: '',//导航提示
                timeDistance: '',//时间距离提示
                imgUrl: '',//指示标志图
                routePanelShow: true,//路线规划面板是否显示
                naviTipsShow: false,//导航提示栏是否显示
                toolboxShow: true,//工具栏是否显示
                naviDisable: true,//当前是否无法导航
                routeForm: {//路线规划表单要素
                    startPoint: '',
                    endPoint: '',
                    resourceRegion: '1',
                    resourceWater: '1',
                    resourceForest: '1'
                },
                clickEvent: null,//地图点击事件
                markerArr: [],
                imitateGuides: [],//模拟导航信息提示数组
                imitatePointList: [],//模拟导航移动途经点数组
                imitateTraces: [],//模拟导航移动路径数据
                wholeDistance: 0,//路径规划总距离
                speed: 60,//默认速度60km/h
                layerIds: [],//图层ID数组
                sourceArr: [],
                flag: 0,//是否转向标识符
                imitateTimeInterval: null,//模拟导航移动定时器
                actualTimeInterval: null,//真实导航移动定时器
                actualLocation: null,//当前真实位置
                actualLocationArr: [],//实时位置点历史数组
                model: null//三维模型
            }
        },
        methods: {
            //mapbox初始化地图
            initMap() {
                this.actualLocation = {}
                this.actualLocationArr.push({...this.actualLocation, m: 0})
                this.$rootMap.map = new mapboxgl.Map({
                    container: 'map-container',
                    center: (location && location.lat) ? new mapboxgl.LngLat(location.lon,location.lat) : new mapboxgl.LngLat(118.7931628, 31.8707908),
                    style: "http://192.168.0.121:5095/bdgis/mapstyle/basic-style.json",
                    zoom: 16,
                    antialias: false,
                })
                let nav = new mapboxgl.NavigationControl()
                this.$rootMap.map.addControl(nav, 'bottom-right')
                let scale = new mapboxgl.ScaleControl({
                    maxWidth: 80,
                    unit: 'imperial'
                })
                this.$rootMap.map.addControl(scale)
                scale.setUnit('metric')
            },
            //actual为false，进行模拟导航，否则进入实时导航
            imitateNavigate(actual = false) {
                this.routePanelShow = false
                this.toolboxShow = false
                this.flag = 0 //标识符归位

                if(actual) {
                    this.actualTimeInterval && clearInterval(this.actualTimeInterval)
                    this.actualLocation = $App.getSelfLocation()
                    this.actualLocationArr.push({...this.actualLocation, m: 0})
                } else {
                    this.imitateTimeInterval && clearInterval(this.imitateTimeInterval)
                }
                //添加模拟导航途径路线图层
                let lineFeature = {
                    type: 'Feature',
                    properties: {},
                    geometry: {
                        type: 'LineString',
                        coordinates: []
                    }
                }
                this.addLineLayer(lineFeature, 'moveLineSource', 'moveLine', 'moveArrow', '#409eff')
                //添加车辆图标
                const iconRotate = -90, iconSize = 0.15
                let carIcon = {
                    type: 'FeatureCollection',
                    features: [{
                        type: 'Feature',
                        geometry: {
                            type: 'Point',
                            coordinates: actual ? [this.actualLocation.lon, this.actualLocation.lat] : [this.imitatePointList[0].longitude, this.imitatePointList[0].latitude]
                        },
                        properties: {
                            bearing: actual ?
                                iconRotate + turf.bearing(turf.point([this.actualLocationArr[0].lon, this.actualLocationArr[0].lat]), turf.point([this.actualLocation.lon, this.actualLocation.lat]))
                                : iconRotate + turf.bearing(turf.point([this.imitatePointList[0].longitude, this.imitatePointList[0].latitude]), turf.point([this.imitatePointList[1].longitude, this.imitatePointList[1].latitude]))
                        }
                    }]
                }
                this.$rootMap.map.loadImage('static/img/car.png', (err, image) => {
                    if (err) {
                        this.$message({
                            showClose: true,
                            message: '加载车辆标识失败',
                            type: 'danger',
                            duration: 2000
                        })
                        throw err
                    }
                    this.$rootMap.map.addSource('iconSource', {
                        type: 'geojson',
                        data: carIcon
                    })
                    this.sourceArr.push('iconSource')
                    this.$rootMap.map.addImage("car-icon", image)
                    this.$rootMap.map.addLayer({
                        id: 'car-layer',
                        type: 'symbol',
                        source: 'iconSource',
                        layout: {
                            'icon-image': 'car-icon',
                            'icon-size': iconSize,
                            'icon-rotate': ['get', 'bearing'],
                            'icon-rotation-alignment': 'map',
                            'icon-allow-overlap': true,
                            'icon-ignore-placement': true
                        }
                    })
                    this.layerIds.push('car-layer')
                    //将起点和终点图标图层置于除车辆图层之外其他图层之上，避免被线压盖
                    this.$rootMap.map.moveLayer('start-layer', 'car-layer')
                    this.$rootMap.map.moveLayer('end-layer', 'car-layer')

                    //加载完成后开始模拟导航
                    if(actual) {
                        this.actualNavigateProcessImproved(lineFeature, carIcon, iconRotate)
                    } else {
                        this.navigateProcessImproved(lineFeature, carIcon, iconRotate)
                    }
                })
            },
            //真实导航轨迹移动处理流程
            actualNavigateProcessImproved(lineFeature, carIcon, iconRotate) {
                let imitatePointList = this.imitatePointList, imitateGuides = this.imitateGuides, guide = imitateGuides[0]
                //设置地图倾斜
                this.$rootMap.map.jumpTo({
                    center: [this.actualLocation.lon, this.actualLocation.lat],
                    pitch: 45,
                    zoom: 18,
                    bearing: turf.bearing(turf.point([this.actualLocationArr[0].lon, this.actualLocationArr[0].lat]), turf.point([this.actualLocation.lon, this.actualLocation.lat]))
                })

                // 展示导航信息
                this.naviTipsShow = true
                this.timeDistance = `剩余：${this.formatSecToDate(parseInt(this.wholeDistance / (this.speed * 0.278)))}，${parseInt(this.wholeDistance)}米` //1km/h=0.278m/s,默认速度60km/h
                this.tips = guide.describe
                this.imgUrl = 'static/img/straight.png'
                setTimeout(() => {
                    this.imgUrl = ''
                }, 2000)

                //定时移动点位置模拟实时导航
                var i = 0, j = 1, m = 0 //i标识模拟点，j标识guides(导航信息)
                this.actualTimeInterval = setInterval(() => {
                    this.actualLocation = $App.getSelfLocation()
                    let len = this.actualLocationArr.length
                    //计算当前点距离初始点的累加距离值
                    m = m + turf.distance(turf.point(this.actualLocationArr[len - 1].lon, this.actualLocationArr[len - 1].lat), turf.point(this.actualLocation.lon, this.actualLocation.lat),{units: 'miles'})
                    //导航模拟点已遍历完，或当前点与终点距离小于20m，判定为结束导航
                    if (Math.abs(this.wholeDistance - m) <= 20) {
                        this.$message({
                            message: '实时导航结束',
                            type: 'info'
                        })
                        this.naviDisable = true
                        clearInterval(this.actualTimeInterval)
                        this.cleanMap()
                        this.naviTipsShow = false
                        this.toolboxShow = true
                        return
                    }

                    //根据下一个点位置是否需要导航提示
                    if (j < imitateGuides.length) {
                        //即将进入下一段路时，进行导航提示
                        if (m <= imitateGuides[j].m - 50) {
                            this.flag++
                            this.tips = imitateGuides[j].describe
                            switch (imitateGuides[j].turnType) {
                                case '直行':
                                    this.imgUrl = 'static/img/straight.png'
                                    setTimeout(() => {
                                        this.imgUrl = ''
                                    }, 2000)
                                    break
                                case '左转':
                                    this.imgUrl = 'static/img/left.png'
                                    setTimeout(() => {
                                        this.imgUrl = ''
                                    }, 2000)
                                    break
                                case '右转':
                                    this.imgUrl = 'static/img/right.png'
                                    setTimeout(() => {
                                        this.imgUrl = ''
                                    }, 2000)
                                    break
                                default:
                                    break
                            }
                            j++
                        }
                    }

                    //修改图标朝向及位置
                    let bearing = turf.bearing(turf.point([this.actualLocationArr[len - 1].lon, this.actualLocationArr[len - 1].lat]), turf.point([this.actualLocation.lon, this.actualLocation.lat]))
                    carIcon.features[0].properties.bearing = bearing + iconRotate
                    carIcon.features[0].geometry.coordinates = [this.actualLocation.lon, this.actualLocation.lat]
                    this.$rootMap.map.getSource('iconSource').setData(carIcon)
                    //更新移动轨迹
                    lineFeature.geometry.coordinates.push([this.actualLocation.lon, this.actualLocation.lat])
                    this.$rootMap.map.getSource('moveLineSource').setData(lineFeature)

                    this.$rootMap.map.jumpTo({center: [this.actualLocation.lon, this.actualLocation.lat]})
                    let a = this.formatSecToDate(parseInt((this.wholeDistance - m) / (this.speed * 0.278)))
                    let b = parseInt(this.wholeDistance - m)
                    // 展示导航信息
                    this.timeDistance = `剩余：${a}，${b}米`

                    //当前刚进入下一段路时，进行地图转向
                    let jActual = j
                    if (this.flag) {
                        jActual = j - this.flag
                    } else if (j >= imitateGuides.length) {
                        jActual = imitateGuides.length - 1
                    }
                    //console.log('actual m:' + m, jActual + ':' + imitateGuides[jActual].m)
                    if (m >= imitateGuides[jActual].m && this.actualLocationArr[len - 1].m < imitateGuides[jActual].m) {
                        /*console.log('转向'+jActual+': '+imitateGuides[jActual].degrees+'计算:'+turf.bearing(
                            turf.point([this.actualLocationArr[len - 1].lon, this.actualLocationArr[len - 1].lat]),
                            turf.point([this.actualLocation.lon, this.actualLocation.lat])
                        ))*/
                        this.$rootMap.map.rotateTo(imitateGuides[jActual].degrees, {duration: 2000, screenSpeed: 2})
                        this.flag-- //标识值归位
                    }

                    //更新轨迹点数组
                    if (len <= 10) { //真实轨迹点最多存储最近的10个点
                        this.actualLocationArr.push({...this.actualLocation, m})
                    } else {
                        this.actualLocationArr.shift()
                        this.actualLocationArr.push({...this.actualLocation, m})
                    }
                }, 2000)
            },
            //模拟导航轨迹移动处理流程
            navigateProcessImproved(lineFeature, carIcon, iconRotate) {
                let imitatePointList = this.imitatePointList, imitateGuides = this.imitateGuides, guide = imitateGuides[0]
                //设置地图倾斜
                this.$rootMap.map.jumpTo({
                    center: [imitatePointList[0].longitude, imitatePointList[0].latitude],
                    pitch: 45,
                    zoom: 18,
                    bearing: turf.bearing(turf.point([imitatePointList[0].longitude, imitatePointList[0].latitude]), turf.point([imitatePointList[1].longitude, imitatePointList[1].latitude]))
                })

                // 展示导航信息
                this.naviTipsShow = true
                this.timeDistance = `剩余：${this.formatSecToDate(parseInt(this.wholeDistance / (this.speed * 0.278)))}，${parseInt(this.wholeDistance)}米` //1km/h=0.278m/s,默认速度60km/h
                this.tips = guide.describe
                this.imgUrl = 'static/img/straight.png'
                setTimeout(() => {
                    this.imgUrl = ''
                }, 2000)

                //定时移动点位置模拟实时导航
                var i = 0, j = 1 //i标识模拟点，j标识guides(导航信息)
                this.imitateTimeInterval = setInterval(() => {
                    //导航模拟点已遍历完，或当前点与终点距离小于20m，判定为结束导航
                    if (i >= imitatePointList.length || Math.abs(this.wholeDistance - imitatePointList[i].m) <= 20) {
                        this.$message({
                            message: '导航结束',
                            type: 'info'
                        })
                        this.naviDisable = true
                        clearInterval(this.imitateTimeInterval)
                        this.cleanMap()
                        this.naviTipsShow = false
                        this.toolboxShow = true
                        return
                    }

                    //根据下一个点位置是否需要导航提示
                    if (j < imitateGuides.length && i < imitatePointList.length - 1) {
                        //即将进入下一段路时，进行导航提示
                        if (imitatePointList[i].m <= imitateGuides[j].m && imitatePointList[i + 1].m >= imitateGuides[j].m) {
                            this.flag++
                            this.tips = imitateGuides[j].describe
                            switch (imitateGuides[j].turnType) {
                                case '直行':
                                    this.imgUrl = 'static/img/straight.png'
                                    setTimeout(() => {
                                        this.imgUrl = ''
                                    }, 2000)
                                    break
                                case '左转':
                                    this.imgUrl = 'static/img/left.png'
                                    setTimeout(() => {
                                        this.imgUrl = ''
                                    }, 2000)
                                    break
                                case '右转':
                                    this.imgUrl = 'static/img/right.png'
                                    setTimeout(() => {
                                        this.imgUrl = ''
                                    }, 2000)
                                    break
                                default:
                                    break
                            }
                            j++
                        }
                    }

                    //修改图标朝向及位置
                    if (i < imitatePointList.length - 1) {
                        let bearing = turf.bearing(turf.point([imitatePointList[i].longitude, imitatePointList[i].latitude]), turf.point([imitatePointList[i + 1].longitude, imitatePointList[i + 1].latitude]))
                        //this.model.setRotation({x: 0, y: 0, z: iconRotate - bearing})
                        carIcon.features[0].properties.bearing = bearing + iconRotate
                    }
                    carIcon.features[0].geometry.coordinates = [imitatePointList[i].longitude, imitatePointList[i].latitude]
                    this.$rootMap.map.getSource('iconSource').setData(carIcon)
                    //this.model.setCoords([this.imitatePointList[i].longitude, this.imitatePointList[i].latitude])
                    //更新移动轨迹
                    if(i > 0) {
                        this.imitateTraces[i - 1].forEach(trace => {
                            lineFeature.geometry.coordinates.push([trace.longitude, trace.latitude])
                        })
                        this.$rootMap.map.getSource('moveLineSource').setData(lineFeature)
                    }

                    carIcon.features[0].geometry.coordinates = [imitatePointList[i].longitude, imitatePointList[i].latitude]
                    this.$rootMap.map.jumpTo({center: [imitatePointList[i].longitude, imitatePointList[i].latitude]})
                    let a = this.formatSecToDate(parseInt((this.wholeDistance - imitatePointList[i].m) / (this.speed * 0.278)))
                    let b = parseInt(this.wholeDistance - imitatePointList[i].m)
                    // 展示导航信息
                    this.timeDistance = `剩余：${a}，${b}米`

                    //当前刚进入下一段路时，进行地图转向
                    let jActual = j
                    if (this.flag) {
                        jActual = j - this.flag
                    } else if (j >= imitateGuides.length) {
                        jActual = imitateGuides.length - 1
                    }
                    if(i > 0 && i < imitatePointList.length - 1) {
                        console.log(i + ':' + imitatePointList[i].m, jActual + ':' + imitateGuides[jActual].m,'i-1:' + imitatePointList[i - 1].m)
                        if (imitatePointList[i].m >= imitateGuides[jActual].m && imitatePointList[i - 1].m < imitateGuides[jActual].m) {
                            /*console.log('转向 turf:' + turf.bearing(
                                turf.point([imitatePointList[i].longitude, imitatePointList[i].latitude]),
                                turf.point([imitatePointList[i + 1].longitude, imitatePointList[i + 1].latitude])
                            ) + '后台:' + imitateGuides[jActual].degrees)*/
                            console.log('转向'+jActual+': '+imitateGuides[jActual].degrees+'计算:'+turf.bearing(
                                turf.point([imitatePointList[i].longitude, imitatePointList[i].latitude]),
                                turf.point([imitatePointList[i + 1].longitude, imitatePointList[i + 1].latitude])
                            ))
                            //this.$rootMap.map.jumpTo({bearing: imitateGuides[jActual].degrees})
                            this.$rootMap.map.rotateTo(imitateGuides[jActual].degrees, {duration: 2000, screenSpeed: 2})
                            this.flag-- //标识值归位
                        }
                    }

                    i++
                }, 3000)
            },
            //路径规划分析
            async routeAnalyze() {
                this.clickEvent && this.$rootMap.map.off('click', this.clickEvent)
                if (!this.routeForm.startPoint) {
                    this.$message({
                        message: '当前未选择起点',
                        type: 'warning'
                    })
                    return
                }
                if (!this.routeForm.endPoint) {
                    this.$message({
                        message: '当前未选择终点',
                        type: 'warning'
                    })
                    return
                }
                if(this.layerIds.indexOf('navigateLine') > -1) {
                    this.$rootMap.map.removeLayer('navigateLine')
                    this.$delete(this.layerIds, this.layerIds.indexOf('navigateLine'))
                    this.$rootMap.map.removeLayer('navigateArrow')
                    this.$delete(this.layerIds, this.layerIds.indexOf('navigateArrow'))
                    this.$rootMap.map.removeSource('navigateLineSource')
                    this.$delete(this.sourceArr, this.sourceArr.indexOf('navigateLineSource'))
                }
                // 箭头-右
                var svgXML =
                    `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
                        <path d="M529.6128 512L239.9232 222.4128 384.7168 77.5168 819.2 512 384.7168 946.4832 239.9232 801.5872z" p-id="9085" fill="#ffffff"></path>
                     </svg>`
                //给图片对象写入base64编码的svg流
                var svgBase64 = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgXML)));
                if (this.$rootMap.map.hasImage('arrowIcon')) {
                    this.$rootMap.map.removeImage('arrowIcon')
                }
                let arrowIcon = new Image(20, 20)
                arrowIcon.src = svgBase64
                arrowIcon.onload = () => {
                    this.$rootMap.map.addImage('arrowIcon', arrowIcon)
                }
                //获取导航相关数据
                let featureObj = await this.getRoutePlanResult();

                if (!featureObj.pointFeature) {
                    this.$message({
                        message: '路径规划失败',
                        type: 'danger'
                    });
                    return
                }
                //跳转到起点
                let firstLng = this.imitatePointList[0].longitude
                let firstLat = this.imitatePointList[0].latitude
                let firstLngLat = new mapboxgl.LngLat(firstLng, firstLat)
                this.$rootMap.map.panTo(firstLngLat)

                let lineFeature = featureObj.lineFeature
                this.addLineLayer(lineFeature, 'navigateLineSource', 'navigateLine', 'navigateArrow', '#31881e')
                this.naviDisable = false
            },
            //获取并处理路径规划结果
            async getRoutePlanResult() {
                let navMesObj = {
                    lineFeature: null,
                    pointFeature: null
                }
                let data = {
                    "isUsingRoad": 1,
                    "isReturnGuide": 1,
                    "nodes": [
                        {"latitude": this.routeForm.startPoint.split(',')[0], "longitude": this.routeForm.startPoint.split(',')[1]},
                        {"latitude": this.routeForm.endPoint.split(',')[0], "longitude": this.routeForm.endPoint.split(',')[1]}
                    ]
                };
                //let res = await axios.post('http://192.168.0.109:4085/route', data)
                let res = $App.routeAnalyze(JSON.stringify(data));
                let result = JSON.parse(res);
                console.log("路径规划信息："+res);
                //let result = res.data

                if (result.data) {
                    this.imitateGuides = result.data.guides
                    this.imitatePointList = result.data.points
                    this.wholeDistance = result.data.length
                    this.imitateTraces = result.data.traces
                    let points = [], traces = result.data.traces
                    let feature = {
                        type: 'Feature',
                        properties: {},
                        geometry: {
                            type: 'LineString',
                            coordinates: []
                        }
                    }
                    for (let i = 0; i < traces.length; i++) {
                        for (let j = 0; j < traces[i].length; j++) {
                            points.push(traces[i][j])
                        }
                    }
                    let pointsSourceData = {
                        type: 'FeatureCollection',
                        features: []
                    }
                    for (let i = 0; i < points.length; i++) {
                        let pointFeature = {
                            type: 'Feature',
                            geometry: {
                                type: 'Point',
                                coordinates: []//coordinates
                            }
                        };
                        let tmpLat = points[i].latitude
                        let tmpLon = points[i].longitude
                        let tmpPoint = [tmpLon, tmpLat]
                        //线的geojson
                        feature.geometry.coordinates.push(tmpPoint)
                        //多个点的geojson
                        if (i > 1) {
                            pointFeature.geometry.coordinates = tmpPoint
                            pointsSourceData.features.push(pointFeature)
                        }
                    }
                    navMesObj.lineFeature = feature
                    navMesObj.pointFeature = pointsSourceData
                }
                return navMesObj
            },
            //动态添加线图层
            addLineLayer(lineFeature, sourceID, layerID, arrowLayerID, color) {
                //添加线图层
                this.$rootMap.map.addSource(sourceID, {
                    'type': 'geojson',
                    'data': lineFeature
                })
                this.sourceArr.push(sourceID)
                this.$rootMap.map.addLayer({
                    id: layerID,
                    type: 'line',
                    source: sourceID,
                    layout: {},
                    paint: {
                        'line-color': color,
                        'line-width': 8
                    }
                })
                this.layerIds.push(layerID)
                //添加箭头图层
                this.$rootMap.map.addLayer({
                    id: arrowLayerID,
                    type: 'symbol',
                    source: sourceID,
                    layout: {
                        'symbol-placement': 'line',
                        'symbol-spacing': 80,
                        'icon-image': 'arrowIcon',
                        'icon-size': 0.5
                    }
                })
                this.layerIds.push(arrowLayerID)
            },
            //地图添加起点
            getStartPoint() {
                this.clickEvent && this.$rootMap.map.off('click', this.clickEvent)

                this.clickEvent = e => {
                    this.routeForm.startPoint = e.lngLat.lat.toFixed(6) + "," + e.lngLat.lng.toFixed(6)
                    let startIcon = {
                        type: 'FeatureCollection',
                        features: [{
                            type: 'Feature',
                            geometry: {
                                type: 'Point',
                                coordinates: [e.lngLat.lng, e.lngLat.lat]
                            }
                        }]
                    }
                    this.$rootMap.map.loadImage('static/img/start.png', (err, image) => {
                        if (err) {
                            this.$message({
                                showClose: true,
                                message: '加载起点标识失败',
                                type: 'danger',
                                duration: 2000
                            })
                            throw err
                        }
                        if (this.sourceArr.indexOf('startSource') >= 0) {
                            if(this.$rootMap.map.hasImage("start-icon")) {
                                this.$rootMap.map.removeImage("start-icon")
                            }
                            if (this.layerIds.indexOf('start-layer') >= 0) {
                                this.$rootMap.map.removeLayer('start-layer')
                                this.$delete(this.layerIds, this.layerIds.indexOf('start-layer'))
                            }
                            this.$rootMap.map.removeSource('startSource')
                            this.$delete(this.sourceArr, this.sourceArr.indexOf('startSource'))
                        }
                        this.$rootMap.map.addSource('startSource', {
                            type: 'geojson',
                            data: startIcon
                        })
                        this.sourceArr.push('startSource')
                        this.$rootMap.map.addImage("start-icon", image)

                        this.$rootMap.map.addLayer({
                            id: 'start-layer',
                            type: 'symbol',
                            source: 'startSource',
                            layout: {
                                'icon-image': 'start-icon',
                                'icon-size': 0.3,
                                'icon-offset': [0, -60],
                                'icon-allow-overlap': true,
                                'icon-ignore-placement': true
                            }
                        })
                        this.layerIds.push('start-layer')
                    })
                }
                this.$rootMap.map.on('click', this.clickEvent)
            },
            //地图添加终点
            getEndPoint() {
                this.clickEvent && this.$rootMap.map.off('click', this.clickEvent);

                this.clickEvent = e => {
                    this.routeForm.endPoint = e.lngLat.lat.toFixed(6) + "," + e.lngLat.lng.toFixed(6)
                    let endIcon = {
                        type: 'FeatureCollection',
                        features: [{
                            type: 'Feature',
                            geometry: {
                                type: 'Point',
                                coordinates: [e.lngLat.lng, e.lngLat.lat]
                            }
                        }]
                    }
                    this.$rootMap.map.loadImage('static/img/end.png', (err, image) => {
                        if (err) {
                            this.$message({
                                showClose: true,
                                message: '加载起点标识失败',
                                type: 'danger',
                                duration: 2000
                            })
                            throw err
                        }
                        if (this.sourceArr.indexOf('endSource') >= 0) {
                            if(this.$rootMap.map.hasImage("end-icon")) {
                                this.$rootMap.map.removeImage("end-icon")
                            }
                            if (this.layerIds.indexOf('end-layer') >= 0) {
                                this.$rootMap.map.removeLayer('end-layer')
                                this.$delete(this.layerIds, this.layerIds.indexOf('end-layer'))
                            }
                            this.$rootMap.map.removeSource('endSource')
                            this.$delete(this.sourceArr, this.sourceArr.indexOf('endSource'))
                        }
                        this.$rootMap.map.addSource('endSource', {
                            type: 'geojson',
                            data: endIcon
                        })
                        this.sourceArr.push('endSource')
                        this.$rootMap.map.addImage("end-icon", image)

                        this.$rootMap.map.addLayer({
                            id: 'end-layer',
                            type: 'symbol',
                            source: 'endSource',
                            layout: {
                                'icon-image': 'end-icon',
                                'icon-size': 0.3,
                                'icon-offset': [0, -60],
                                'icon-allow-overlap': true,
                                'icon-ignore-placement': true
                            }
                        })
                        this.layerIds.push('end-layer')
                    })
                }
                this.$rootMap.map.on('click', this.clickEvent)
            },
            //时间转换
            formatSecToDate(sec) {
                if (!sec) {
                    return '-'
                }
                let min = Math.floor(sec % 3600);//分钟
                return Math.floor(sec / 3600) + "小时" + Math.floor(min / 60) + "分" + sec % 60 + "秒";
            },
            //显示路线规划表单面板
            showRoutePanel() {
                this.routePanelShow = true
            },
            //清除地图规划导航图层要素
            cleanMap() {
                this.routeForm.startPoint = ''
                this.routeForm.endPoint = ''
                //根据id删除所有的图层，图层被占用无法删除source
                if (this.layerIds.length) {
                    this.layerIds.forEach((item) => {
                        this.$rootMap.map.removeLayer(item)
                    })
                }
                //删除所有source
                if (this.sourceArr.length) {
                    this.sourceArr.forEach(item => {
                        this.$rootMap.map.removeSource(item)
                    })
                }
                this.layerIds = []
                this.sourceArr = []
            },
            shutDownNavigate() {
                this.$message({
                    message: '导航结束',
                    type: 'info'
                })
                this.naviTipsShow = false
                this.routePanelShow = true
                this.toolboxShow = true
                this.imitateTimeInterval && clearInterval(this.imitateTimeInterval)
                this.actualTimeInterval && clearInterval(this.actualTimeInterval)
                this.cleanMap()
            },
            backToAddress() {
                this.$router.push("/map");
            },
        },
        mounted() {
            this.initMap()
            if(this.$route.query.startPoint) {
                let startPoint = this.$route.query.startPoint, endPoint = this.$route.query.endPoint
                startPoint.latitude = parseFloat(startPoint.latitude)
                startPoint.longitude = parseFloat(startPoint.longitude)
                endPoint.latitude = parseFloat(endPoint.latitude)
                endPoint.longitude = parseFloat(endPoint.longitude)
                this.$rootMap.map.jumpTo({center: [startPoint.longitude, startPoint.latitude], zoom: 12})
                this.routeForm.startPoint = startPoint.latitude.toFixed(6) + "," + startPoint.longitude.toFixed(6)
                let startIcon = {
                    type: 'FeatureCollection',
                    features: [{
                        type: 'Feature',
                        geometry: {
                            type: 'Point',
                            coordinates: [startPoint.longitude, startPoint.latitude]
                        }
                    }]
                }
                this.$rootMap.map.loadImage('static/img/start.png', (err, image) => {
                    if (err) {
                        this.$message({
                            showClose: true,
                            message: '加载起点标识失败',
                            type: 'danger',
                            duration: 2000
                        })
                        throw err
                    }
                    if (this.sourceArr.indexOf('startSource') >= 0) {
                        if(this.$rootMap.map.hasImage("start-icon")) {
                            this.$rootMap.map.removeImage("start-icon")
                        }
                        if (this.layerIds.indexOf('start-layer') >= 0) {
                            this.$rootMap.map.removeLayer('start-layer')
                            this.$delete(this.layerIds, this.layerIds.indexOf('start-layer'))
                        }
                        this.$rootMap.map.removeSource('startSource')
                        this.$delete(this.sourceArr, this.sourceArr.indexOf('startSource'))
                    }
                    this.$rootMap.map.addSource('startSource', {
                        type: 'geojson',
                        data: startIcon
                    })
                    this.sourceArr.push('startSource')
                    this.$rootMap.map.addImage("start-icon", image)

                    this.$rootMap.map.addLayer({
                        id: 'start-layer',
                        type: 'symbol',
                        source: 'startSource',
                        layout: {
                            'icon-image': 'start-icon',
                            'icon-size': 0.3,
                            'icon-offset': [0, -60],
                            'icon-allow-overlap': true,
                            'icon-ignore-placement': true
                        }
                    })
                    this.layerIds.push('start-layer')
                })
                this.routeForm.endPoint = endPoint.latitude.toFixed(6) + "," + endPoint.longitude.toFixed(6)
                let endIcon = {
                    type: 'FeatureCollection',
                    features: [{
                        type: 'Feature',
                        geometry: {
                            type: 'Point',
                            coordinates: [endPoint.longitude, endPoint.latitude]
                        }
                    }]
                }
                this.$rootMap.map.loadImage('static/img/end.png', (err, image) => {
                    if (err) {
                        this.$message({
                            showClose: true,
                            message: '加载终点标识失败',
                            type: 'danger',
                            duration: 2000
                        })
                        throw err
                    }
                    if (this.sourceArr.indexOf('endSource') >= 0) {
                        if(this.$rootMap.map.hasImage("end-icon")) {
                            this.$rootMap.map.removeImage("end-icon")
                        }
                        if (this.layerIds.indexOf('end-layer') >= 0) {
                            this.$rootMap.map.removeLayer('end-layer')
                            this.$delete(this.layerIds, this.layerIds.indexOf('end-layer'))
                        }
                        this.$rootMap.map.removeSource('endSource')
                        this.$delete(this.sourceArr, this.sourceArr.indexOf('endSource'))
                    }
                    this.$rootMap.map.addSource('endSource', {
                        type: 'geojson',
                        data: endIcon
                    })
                    this.sourceArr.push('endSource')
                    this.$rootMap.map.addImage("end-icon", image)

                    this.$rootMap.map.addLayer({
                        id: 'end-layer',
                        type: 'symbol',
                        source: 'endSource',
                        layout: {
                            'icon-image': 'end-icon',
                            'icon-size': 0.3,
                            'icon-offset': [0, -60],
                            'icon-allow-overlap': true,
                            'icon-ignore-placement': true
                        }
                    })
                    this.layerIds.push('end-layer')
                })
            }
        },
        beforeDestroy() {
            this.cleanMap()
            this.$rootMap.map.remove()
        }
    }
</script>

<style lang="scss">
    .navigate {
        position: relative;
        width: 100%;
        height: 100%;
        .header {
            position: absolute;
            width: 100%;
            background-color: #03192b;
            color: #ffffff;
            .van-nav-bar__title {
                color: #ffffff;
            }
            .van-icon {
                color: #ffffff;
            }
        }
        #map-container {
            width: 100%;
            height: 100%;
        }
        .toolbox {
            position: absolute;
            top: 20%;
            right: 0px;
            z-index: 2023;
            display: flex;
            flex-direction: column;
            div {
                width: 45px;
                height: 45px;
                border-radius: 10px;
                background: white;
                margin-top: 5px;
                display: flex;
                justify-content: center;
                align-items: center;
                img {
                    width: 100%;
                    height: 100%;
                }
            }
        }
        .navi-tips {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 2023;
            width: 100%;
            i {
                position: absolute;
                top: 10px;
                right: 10px;
                font-size: 18px;
                color: #ffffff;
                cursor: pointer;
            }
            .tips-wrapper {
                background: rgba(0,0,0,0.8);
                color: #fff;
                border-radius: 10px;
                font-size: 18px;
                padding: 20px 30px;
                .tips {
                    margin-bottom: 20px;
                }
            }
            img {
                width: 150px;
                position: absolute;
                bottom: -170px;
                left: 50%;
                transform: translateX(-50%);
            }
        }
        .routePanel {
            position: absolute;
            bottom: 0;
            left: 0;
            z-index: 2023;
            width: 100%;
            background-color: rgba(255, 255, 255, 1);
            padding: 20px 20px 10px;
        }
        .el-collapse-item__header {
            height: 30px;
            color: #c0c4cc;
        }

        .el-form-item {
            margin-top: 20px !important;
        }

        .el-input__inner {
            background-color: #eee;
            border-radius: 5px;
        }

        .item-btn > div {
            display: flex !important;
            flex-direction: row !important;
            justify-content: space-between !important;
        }

        .el-collapse-item__header {
            background-color: #eee;
            padding-left: 15px;
            border-radius: 5px;
        }

        .el-collapse-item__content > div {
            margin-top: 3px !important;
        }
    }
</style>